package it.uniroma2.controller;

import it.uniroma2.cloud.PROVIDER;
import it.uniroma2.jcloudstests.Command;

import java.util.Collection;
import java.util.Set;

import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.RunScriptOnNodesException;
import org.jclouds.compute.domain.NodeMetadata;

public class Controller {
	
	private static Controller controller;
//	private LoadChecker loadChecker;
//	private LatencyChecker latencyChecker;

	private Controller(){

	}
	
	public static Controller getInstance(){
		if(controller == null){
			controller = new Controller();
		}
		return controller;
	}

	public void addWorkerNode(PROVIDER provider, int howMany) {
		Command cmd = resolveProvider(provider);
		try {
			Set<? extends NodeMetadata> nodes = cmd.createInstances(Command.WORKERNODE, howMany);
			cmd.installWorkerNodeApp(provider, nodes);
			Collection<String> ips = cmd.getPrivateIpsInGroup(Command.WORKERNODE);
			cmd.updateLoadBalancer(ips);
		} catch (RunNodesException e) {
			e.printStackTrace();
		} catch (RunScriptOnNodesException e) {
			e.printStackTrace();
		}
	}

	private Command resolveProvider(PROVIDER provider) {
		Command cmd;
		if (provider == PROVIDER.AWS_EC2){
			cmd = ControllerContextListener.getCloudConfig().getAwsCommand();
		}
		else{
			cmd = ControllerContextListener.getCloudConfig()
					.getCloudstackCommand();
		}
		return cmd;
	}
	
	public String getLoadBalancerAddress(PROVIDER provider){
		Command cmd = resolveProvider(provider);
		return cmd.getLoadBalancerAddress();
	}

	public void destroyWorkerNode(PROVIDER provider, String ip) {
		Command cmd = resolveProvider(provider);
		NodeMetadata node = cmd.getNodeByReachableIp(Command.WORKERNODE, ip);
		//Update LB
		String privateLbIp = null;
		if(provider == PROVIDER.AWS_EC2){
			privateLbIp = node.getPrivateAddresses().iterator().next();
		}else{
			privateLbIp = ip;
		}
		Collection<String> ips = cmd.getPrivateIpsInGroup(Command.WORKERNODE);
		for (String toRemove : ips){
			if(toRemove.equals(privateLbIp)){
				ips.remove(toRemove);
				break;
			}
		}
		cmd.updateLoadBalancer(ips);
		// remove node
		cmd.destroyNode(node);
	}
	
	public static void main(String[] args){
		Controller controller = new Controller();
//		controller.destroyWorkerNode(PROVIDER.CLOUDSTACK, "192.168.3.49");

		System.out.println("ciao");
		controller.addWorkerNode(PROVIDER.OPENSTACK, 1);
		controller.addWorkerNode(PROVIDER.AWS_EC2, 1);
	}
}
